use crate::base::{get_ch_pool, get_work_path, SqlList};
use aho_corasick::AhoCorasick;
use once_cell::sync::Lazy;
static AHO_MAP: Lazy<dashmap::DashMap<String, AhoCorasick>> = Lazy::new(|| dashmap::DashMap::new());
/// 解析sql,替换参数
fn sql_parse(sql: &str, params_names: &[&str], params_vals: &[&str]) -> anyhow::Result<String> {
    let name = params_names.join("|");
    if !AHO_MAP.contains_key(&name) {
        let ac = AhoCorasick::builder().build(params_names).unwrap();
        AHO_MAP.insert(name.clone(), ac);
    }
    let ac = AHO_MAP.get(&name).unwrap();
    let mut wtr = vec![];
    ac.try_stream_replace_all(sql.as_bytes(), &mut wtr, params_vals)
        .expect("字符串替换失败");
    let sql = String::from_utf8(wtr)?;
    Ok(sql)
}
pub fn is_exist_sql(sl: &SqlList) -> bool {
    match sl {
        SqlList::Vec(sqls) => !sqls.is_empty(),
        SqlList::Path(file_name) => {
            let file_path=if file_name.ends_with(".sql") {
                format!("{}/sqls/{}", get_work_path(), file_name)
            }else{
                format!("{}/sqls/{}.sql", get_work_path(), file_name)
            };
            std::path::Path::new(&file_path).exists()
        }
    }
}
pub async fn exec_sqls(
    sl: &SqlList,
    params_names: &[&str],
    params_vals: &[&str],
) -> anyhow::Result<()> {
    let mut client = get_ch_pool().get_handle().await?;
    let sqls_str = match sl {
        SqlList::Vec(sqls) => sql_parse(&sqls.join(";"), params_names, params_vals)?,
        SqlList::Path(file_name) => {
            let file_path=if file_name.ends_with(".sql") {
                format!("{}/sqls/{}", get_work_path(), file_name)
            }else{
                format!("{}/sqls/{}.sql", get_work_path(), file_name)
            };
            let sqls = std::fs::read_to_string(file_path)?;
            sql_parse(sqls.as_str(), params_names, params_vals)?
        }
    };
    let vec: Vec<&str> = sqls_str.split(';').collect();
    for sql in vec {
        let sql=sql.trim();
        if sql.is_empty() {
            continue;
        }
        client.execute(sql).await?;
    }
    Ok(())
}
